package ofdinv

import (
	"encoding/xml"
	"fmt"
	"strconv"
	"strings"
)

// Document 表示OFD文档结构
type Document struct {
	XMLName    xml.Name   `xml:"Document"`   // XML元素名称，标识文档根元素
	CommonData CommonData `xml:"CommonData"` // 文档公共数据，包含文档级共享信息
	Pages      Pages      `xml:"Pages"`      // 页面集合，包含文档中所有页面的引用
	CustomTags string     `xml:"CustomTags"` // 自定义标签文件路径，指向CustomTags.xml文件
}

// CommonData 表示文档公共数据
type CommonData struct {
	XMLName       xml.Name       `xml:"CommonData"`   // XML元素名称，标识公共数据区域
	MaxUnitID     string         `xml:"MaxUnitID"`    // 最大单元ID，用于资源管理和唯一标识分配
	TemplatePages []TemplatePage `xml:"TemplatePage"` // 模板页面引用集合，定义文档可用的模板
	PublicRes     string         `xml:"PublicRes"`    // 公共资源文件路径，指向共享资源文件
	DocumentRes   string         `xml:"DocumentRes"`  // 文档资源文件路径，指向文档特定资源文件
}

// TemplatePage 表示模板页面引用
type TemplatePage struct {
	XMLName xml.Name `xml:"TemplatePage"` // XML元素名称，标识模板页面引用
	ID      int      `xml:"ID,attr"`      // 模板唯一标识符，用于引用和查找特定模板
	BaseLoc string   `xml:"BaseLoc,attr"` // 模板文件路径，指向模板内容文件的位置
}

// Pages 表示页面集合
type Pages struct {
	XMLName xml.Name  `xml:"Pages"` // XML元素名称，标识页面集合
	Page    []PageRef `xml:"Page"`  // 页面引用数组，每个元素指向一个具体的页面
}

// PageRef 表示页面引用
type PageRef struct {
	XMLName xml.Name `xml:"Page"`         // XML元素名称，标识页面引用
	ID      int      `xml:"ID,attr"`      // 页面唯一标识符，用于区分不同页面
	BaseLoc string   `xml:"BaseLoc,attr"` // 页面文件路径，指向页面内容文件的位置
}

// CustomTagsRoot 表示CustomTags.xml根结构，包含自定义标签文件引用
type CustomTagsRoot struct {
	XMLName   xml.Name        `xml:"CustomTags"` // XML根元素，标识CustomTags.xml文档结构
	CustomTag []CustomTagItem `xml:"CustomTag"`  // 自定义标签项数组，每个元素指向一个具体的自定义标签文件
}

// CustomTagItem 表示自定义标签项，定义单个自定义标签文件的引用信息
type CustomTagItem struct {
	XMLName xml.Name `xml:"CustomTag"`   // XML元素名称，标识自定义标签项
	TypeID  string   `xml:"TypeID,attr"` // 类型标识符，标识自定义标签的业务类型
	FileLoc string   `xml:"FileLoc"`     // 文件路径，指向实际的自定义标签文件位置
}

type Boundary struct {
	X float64 // 文本起始点的X坐标
	Y float64 // 文本起始点的Y坐标
	W float64 // 文本起始点的W宽度
	H float64 // 文本起始点的H高度
}

func (b *Boundary) UnmarshalXMLAttr(attr xml.Attr) error {
	// 解析属性值格式 "X Y W H"
	parts := strings.Fields(attr.Value)
	if len(parts) != 4 {
		return fmt.Errorf("invalid boundary format: %s", attr.Value)
	}

	var err error
	if b.X, err = strconv.ParseFloat(parts[0], 64); err != nil {
		return err
	}
	if b.Y, err = strconv.ParseFloat(parts[1], 64); err != nil {
		return err
	}
	if b.W, err = strconv.ParseFloat(parts[2], 64); err != nil {
		return err
	}
	if b.H, err = strconv.ParseFloat(parts[3], 64); err != nil {
		return err
	}

	return nil
}

type DeltaX []float64

// UnmarshalXMLAttr 实现XML属性解析接口，将字符串如"3.175 3.175"解析为DeltaX切片
func (d *DeltaX) UnmarshalXMLAttr(attr xml.Attr) error {
	if attr.Value == "" {
		*d = []float64{} // 空属性值返回空切片
		return nil
	}

	parts := strings.Fields(attr.Value)
	result := make([]float64, len(parts))
	for i, part := range parts {
		val, err := strconv.ParseFloat(part, 64)
		if err != nil {
			return fmt.Errorf("invalid DeltaX value '%s': %v", attr.Value, err)
		}
		result[i] = val
	}
	*d = result
	return nil
}

// Sum 返回DeltaX切片中所有元素的和
func (d DeltaX) Sum() float64 {
	sum := 0.0
	for _, val := range d {
		sum += val
	}
	return sum
}

// 根据tplID获取aseLoc路径文本
func (d *Document) GetTplBaseLocByID(id int) string {
	tplPages := d.CommonData.TemplatePages
	for _, tplPage := range tplPages {
		if tplPage.ID == id {
			return tplPage.BaseLoc
		}
	}
	return ""
}

// getPagePath 根据页面ID获取页面文件路径
func (p *Pages) GetPagePath(pageID int) (string, error) {
	for _, pageRef := range p.Page {
		if pageRef.ID == pageID {
			return pageRef.BaseLoc, nil
		}
	}
	return "", fmt.Errorf("未找到页面ID %d 的映射", pageID)
}
